/**
 * 
 */
package de.guidoludwig.jtm;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import de.guidoludwig.jtm.util.JTMUtil;
import de.guidoludwig.jtm.util.StringUtil;

/**
 * @author guido
 *
 */
public class Migrator {

	private static Migrator INSTANCE;
	private static final String VERSION_TABLE_NAME = "JTM_VERSION";
	
	private Connection connection;
	private int currentVersion;
	
	public static Migrator getInstance() throws ClassNotFoundException {
		if (INSTANCE == null) {
			INSTANCE = new Migrator();
		}
		return INSTANCE;
	}
	
	private Migrator()  {
		// NO
	}
	
	/**
	 * 
	 * @param dbName dbName with full path
	 * @throws SQLException
	 * @throws ClassNotFoundException
	 * @throws IOException
	 */
	public void migrate(String dbName) throws SQLException, ClassNotFoundException, IOException {
		Class.forName("org.sqlite.JDBC");
		File file = new File(dbName);
		if (!file.exists()) {
			String[] tokens = dbName.split("/");
			String path = "";
			for (int i = 0; i < tokens.length-1; i++) {
				path = path+tokens[i];
				File f = new File(path);
				f.mkdir();
			}
		}
		connection = DriverManager.getConnection("jdbc:sqlite:" + dbName);
		getCurrentVersion();
		performMigration();
		connection.close();
	}

	private void performMigration() throws IOException, SQLException {
		BufferedReader reader = JTMUtil.loadResourceFile("migrator.sql");
		String line;
		int migratorVersion = 0;
		while ((line = reader.readLine()) != null) {
			if (line.startsWith("#") || StringUtil.isBlank(line)) {
				continue;
			}
			migratorVersion ++;
			if (migratorVersion > currentVersion) {
				Statement s = connection.createStatement();
				s.execute(line);
				currentVersion = migratorVersion;
				s.execute("INSERT into " + VERSION_TABLE_NAME + " VALUES(date('now'), " + currentVersion + ")");
				s.close();
			}
		}
		getCurrentVersion();
	}

	private void getCurrentVersion() throws SQLException {
		Statement s = connection.createStatement();
		s.execute("create table if not exists " + VERSION_TABLE_NAME + "(updateDate TEXT, version INTEGER)");
		s.close();
		s = connection.createStatement();
		s.execute("select max(version+0) from " + VERSION_TABLE_NAME);
		currentVersion = 0;
		ResultSet rs = s.getResultSet();
		if (rs.next()) {
			currentVersion = rs.getInt(1);
		}
		System.out.println("Current Version : " + currentVersion);
		s.close();
	}
	
	
}
